#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define N 10

void RunChild()
{
    int cnt = 5;
    while(cnt)
    {
        printf("I am Child Process, pid: %d, ppid: %d\n",getpid(),getppid());
        sleep(1);
        cnt--;
    }
}

// int main()
// {
//     // wait / waitpid
//     for(int i = 0;i < N;i++)
//     {
//         pid_t id = fork();
//         if(id == 0)
//         {
//             RunChild();
//             exit(i);
//         }
//         printf("create child process: %d success\n",id);
//         // 这句话只有父进程才会执行
//     }
//     
//     sleep(10);
// 
//     // 等待
//     for(int i = 0;i < N;i++)
//     {
//         // pid_t id = wait(NULL);
//         int status = 0;
//         pid_t id = waitpid(-1,&status,0);
//         if(id > 0)
//         {
//             printf("wait %d success, exit code: %d\n",id,WEXITSTATUS(status));
//         }
//     }
// 
//     sleep(5);
//     
//     return 0;
// }

int main()
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork");
        return 1;
    }
    else if(id == 0)
    {
        // child
        
        int cnt = 5;
        while(cnt)
        {
            printf("I am child, pid:%d, ppid:%d, cnt: %d\n",getpid(),getppid(),cnt);
            cnt--;
            sleep(1);
        }
        exit(0);
    }
    else 
    {
        // parent
        
        // int cnt = 10;
        // while(cnt)
        // {
        //     printf("I am father, pid:%d, ppid:%d, cnt: %d\n",getpid(),getppid(),cnt);
        //     cnt--;
        //     sleep(1);
        // }
        // 目前为止，进程等待是必须的
        // wait是等待任意一个子进程退出
        int status = 0;
        // pid_t ret = waitpid(id,&status,0);
        
        while(1)
        {
            pid_t ret = waitpid(id,&status,WNOHANG);
            if(ret > 0)
            {
                // 7F: 0111 1111
                // printf("success wait,ret: %d, exit sig: %d, exit code: %d\n",ret,status&0x7F, (status>>8)&0xFF);
                if(WIFEXITED(status))
                {
                    printf("进程是正常跑完的，退出码：%d\n",WEXITSTATUS(status));
                }
                else 
                {
                    printf("进程出异常了\n");
                }
                break;
            }
            else if(ret < 0) 
            {
                printf("wait failed!\n");
                break;
            }
            else 
            {
                // ret = 0
                printf("子进程还没有退出,我再等等...\n");
                // sleep(1);
            }
        }
    }
    sleep(5);

    return 0;
}
